import axios from "axios";
import qs from "qs";
import { Store, StoreTypeLocation, StoreTypeSesion } from "./store";
import Yangsu from "./yangsu";
import { useRouter } from "vue-router";
import { showLoadingToast } from "vant";

// 页面常量
const _wapHomeUrlKey = `_ys_wap_home_url`, //通过 sessionStorage 保存的全局变量
  _wapGlobalValueKey = "_ys_wap_win_global", //通过 windows 保存当前页码（非刷新的全部变量）
  _wapSsLoginKey = "_ys_wap_user_key_sess", //通过 sessionStorage 保存当前用户登录信息
  // _wapSessionHoldKey = process.env.SESSIN_STORE_KEY || "YANGSU_FOREVEVR" //session 保留键（通过配置获取）
  _wapSessionHoldKey = "YANGSU_FOREVEVR" //session 保留键（通过配置获取）
  ;

const $store = new Store(_wapSessionHoldKey), //存储器
  $yangsu = new Yangsu();

//内部全家变量
let _userInfo: LoginUserInfoTy | null = null,
  _userIsLogin = false;

/**
 * 存储器
 * @param {*} storeType
 */
function store(storeType?: string) {
  return new Store(_wapSessionHoldKey, storeType);
}

// Wap 公共页面
class Wap {
  /**
     * 获取项目的首页地址或设置当前的页码为首页地址
     * @param {boolean|undefined} [setUrl]
     */
  static homeUrl(setUrl: string) {
    if (setUrl) {
      $store.setValue(_wapHomeUrlKey, location.pathname);
    } else {
      return $store.getValue(_wapHomeUrlKey) || "./index.html";
    }
  }
  /**
     * 全局变量处理（KV 存储库）
     * @param {string} key
     * @param {*} [value] 设置为 `null` 则删除变量，不设置为获取变量，设置修改变量
     */
  static global(key: string, value?: any) {
    let wgv = (window as any)[_wapGlobalValueKey] || {};
    let hasKey = ("undefined" === typeof wgv[key]);
    // 删除键值
    if (null === value) {
      if (hasKey) {
        delete wgv[key];
        (window as any)[_wapGlobalValueKey] = wgv;
      }
      return null;
    } else if ("undefined" === typeof value) {
      return wgv[key];
    } else {
      wgv[key] = value;
      (window as any)[_wapGlobalValueKey] = wgv;
    }
    return;
  }
  /**
     * 获取随机数字串
     * @return {string}
     */
  static getRandom() {
    let random: string = `${Math.random()}`;
    random = random.substring(1);
    return random;
  }

  /**
     * 首页跳转（延迟执行）
     * @param  {string} [msg]
     * @param {number} [duration]
     */
  static goHomeDelay(msg?: string, duration?: number) {
    duration = duration ? duration : 3;
    duration = duration * 1000;
    let loading = showLoadingToast({
      message: msg ? msg : "登录已失效...",
      forbidClick: true,
      duration,
    });
    setTimeout(() => {
      loading.close();
      this.goHome();
    }, duration);
  }

  /**
   * 跳转至用户中心
   */
  static goHome() {
    const router = useRouter();
    if (router) {
      router.push("/user");
    } else {
      location.href = "/#/user";
    }

  }

  /**
     * 首页跳转（延迟执行）
     * @param  {CallableFunction} [todo]
     * @param  {string} [msg]
     * @param {number} [duration]
     */
  static delayTodo(todo: () => void, msg?: string, duration?: number) {
    duration = duration ? duration : 3;
    duration = duration * 1000;
    let loading = showLoadingToast({
      message: msg ? msg : "登录已失效...",
      forbidClick: true,
      duration,
    });
    setTimeout(() => {
      loading.close();
      todo();
    }, duration);
  }

  /**
     * 请求用户登录
     * @param {*} data
     */
  static checkRequest(data: any) {
    if ($yangsu.unloginByData(data)) {
      this.loginQuit();
      return true;
    }
    return false;
  }

  /**
   * 登录退出
   */
  static loginQuit() {
    _userIsLogin = false;
    _userInfo = null;
    $store.getNs(_wapSsLoginKey).delValue();
  }

  /**
     * 请求用户登录(延期执行)
     * @param data
     * @return {boolean}
     */
  static checkRequestDelay(data: any) {
    if (this.checkRequest(data)) {
      this.goHomeDelay();
      return true;
    }
    return false;
  }

  /**
     * 用于post请求数据
     * @param  {string} url
     * @param {object} [sendData]
     * @param {object} [option] 选项 {login: bool}
     * @return {Promise<unknown>}
     */
  static post(url: string, sendData: any, option?: any): Promise<ApiFeedData> {
    option = option || {};
    option = Object.assign({
      login: true, //登录检测
    }, option);
    return new Promise((resolve, reject) => {
      if (sendData) {
        sendData = qs.stringify(sendData, { indices: false });
      }
      axios.post(url, sendData)
        .then((response) => {
          let result = response.data;
          if (option.login && this.checkRequestDelay(result)) {
            return;
          }
          resolve(result);
        }).catch(reject);
    });
  }

  /**
   * 用于post请求数据
   * @param  {string} url
   * @param {object} [sendData]
   * @param {object} [option] 选项 {login: bool}
   * @return {Promise<unknown>}
   */
  static get(url: string, option?: any): Promise<ApiFeedData> {
    option = Object.assign({
      login: true, //登录检测
    }, option);
    return new Promise((resolve, reject) => {
      axios.get(url)
        .then((response) => {
          let result = response.data;
          if (option.login && this.checkRequestDelay(result)) {
            return;
          }
          resolve(result);
        }).catch((error) => {
          reject(error);
        });
    });
  }

  /**
   * 请求数据处理
   * @param result
   * @return {Promise<unknown>}
   */
  static resolveResponse(result: any): Promise<KvObj> {
    return new Promise((resolve, reject) => {
      if ("ok" === result.status) {
        resolve(result.data);
      } else {
        reject(result.msg);
      }
    });
  }

  /**
   * 获取日期的字符串格式
   * @param {Date} [vdate]
   * @param {string} [sep]
   */
  static dateFormat(vdate?: Date, sep?: string) {
    vdate = vdate || (new Date());
    sep = sep || "-";
    let month = vdate.getMonth() + 1;
    //month = month < 10 ? `0${month}` : month;
    let day = vdate.getDate();
    let queue = [
      vdate.getFullYear(),
      (month < 10 ? '0' : '') + month,
      day < 10 ? `0${day}` : day,
    ];
    return queue.join(sep);
  }

  // 根据记住状态实现-用户登录
  static saveLgRemeberUser(userInfo: KvObj | false) {
    if (false === userInfo) {
      localStorage.removeItem("yzs-rm-hash");
      return;
    }
    const remember_hash = userInfo.remember_hash;
    if (!remember_hash) {
      return;
    }

    localStorage.setItem("yzs-rm-hash", remember_hash);
  }

  // 根据记住的hash 登录用户
  static loginRememberHash(success_clbk?: () => void) {
    const remember_hash = localStorage.getItem("yzs-rm-hash");
    if (!remember_hash) {
      return;
    }

    this.post("/api/login/remember/hash", { hash: remember_hash })
      .then((result) => {
        if ('ok' == result.status) {
          if (success_clbk) {
            success_clbk();
          }
        }
      })
      .catch((er) => {
        console.log(`自动登录错误，${er}`);
      });
  }

  // 获取信息详情信息
  static systemInfo(success_clbk: (data: SystemInfo) => void) {
    const cache_key = 'sys_info';
    let sys_info_data: SystemInfo = {
      server: null,
      version: import.meta.env.VITE_VERSION,
      release: import.meta.env.VITE_RELEASE,
    }
    const cache = store(StoreTypeSesion);
    const sys_info = cache.getValue(cache_key);
    if (sys_info) {
      success_clbk(sys_info);
      return;
    }

    this.get('/api/system').then((resp) => {
      if (resp.status !== "ok") {
        success_clbk(sys_info_data);
        return
      }

      const result = resp.data.info;
      sys_info_data.server = result;
      cache.setValue(cache_key, sys_info_data);
      success_clbk(sys_info_data);
    }).catch((er) => {
      console.log("system 新增获取失败！", er);
      success_clbk(sys_info_data);
    })

  }
}

// 用户配置信息
interface UserConfig extends KvObj {
  onData?: (userInfo?: KvObj) => void
}

//处理信息
class User {
  _config: UserConfig
  _uInfoKey: string
  _store: Store
  /**
     * 启动数据项
     * @param {object} [config] {onData: (data)=>{}, }
     */
  constructor(config?: UserConfig) {
    this._config = config || {};
    this._store = $store.getNs(_wapSsLoginKey);
    this._uInfoKey = "uinfo";
    this.requestInfo();
  }
  /**
     * 获取是存在用户登录
     */
  get isLogin() {
    return _userIsLogin;
  }
  /**
     * 获取当前的用户信息
     */
  get info() {
    return _userInfo;
  }
  /**
     * 请求用户信息
     * @param {*} [flushMk]
     */
  requestInfo(flushMk?: boolean) {
    let user = this._store.getValue(this._uInfoKey);
    let callOnData = this._config.onData || null;
    callOnData = ("function" === typeof callOnData) ? callOnData : this.onData;
    if (user) {
      _userInfo = user;
      _userIsLogin = true;
    }

    if (callOnData && !flushMk && _userInfo) {
      // 更改函数内部`this`的指向
      callOnData.call(this, _userInfo);
      return;
    }
    //用户登录检测
    axios
      .post("/square/data/square/userinfo")
      .then((response) => {
        let result = response.data;
        if (result.status === "ok") {
          _userInfo = result.data;
          _userIsLogin = true;
          this._store.setValue(this._uInfoKey, _userInfo);
        } else {
          _userIsLogin = false;
          _userInfo = null;
          this._store.delValue(this._uInfoKey);
        }
        if (callOnData) {
          callOnData.call(this, result?.data);
        }
      })
      .catch((error) => {
        console.log(error);
      });
  }
  /**
     * 获取登录信息
     * @param {*} result
     */
  onData(userInfo?: KvObj) {
    console.log(userInfo);
  }
}

export { store, StoreTypeLocation, StoreTypeSesion, User, Wap };
